/* Pre-require: mootools-core.js */
WF = {
	container: null,
	Tab:null,
	loadingImg:null,
	isWebApp:location.search.toLowerCase().indexOf("mode=debug")<0,

	/* state */
	map:null,
	titleTag:null,
	header:null,
	hasTab:false,
	commands:null,
	activePageLink:"http://"+location.host+location.pathname,
	
	/* views stack */
	views: [],
	initIPhone:function() {
		if (window.top!==window.self) return; // do not load in iframe
		
		if (typeof MooTools == "undefined") {
			alert("Please load the mootools script first");
			return;
		}
		
		WF.container = document.body;

		if (!Browser.Platform.ipod) {
			var div = new Element("div", {
				"styles": {
					"width":"320px",
					"height":"460px",
					"left":"40px",
					"top":"154px",
					"position":"relative",
					"overflow":"auto",
					"overflowX":"hidden"
				}
			});

			while (document.body.firstChild&&document.body.firstChild!==div) {
				div.appendChild(document.body.firstChild);
			}
			div.injectInside(document.body);
			WF.container = div;
			__gap = true;
			
			$(document.body).addClass("simulator");
		}
		
		WF.initIPhoneView();
		
		if (!WF.isWebApp) {
			WF.fixScroll();	
		}
		
		// Load default Tab Page
		if (WF.Tab&&WF.Tab.items.length) {
			WF.loadTabContent(WF.Tab.items[0]);
		}
				
		setTimeout(WF.scrollToTop, 500);
		
		setTimeout(function() {
			if (typeof __gap!="undefined"&&__gap) {
				$(WF.container).addClass("gap");
			}
		}, 500);

		window.addEvent("unload", function(){
			if (typeof GUnload!="undefined")
				GUnload();
		});
	},
	
	scrollToTop: function() {
		if (Browser.Platform.ipod) {
			scrollTo(0, 1);	
		}
		else {
			WF.container.scrollTop = 0;	
		}				
	},
	
	initIPhoneView:function() {
		WF.buildHeader();
		WF.buildTab();
		WF.initIPhoneContent();
		WF.initBackButton();
		WF.clearFloat();
		WF.fixIE();
		
		WF.fixHeaderAndTab();

		if ($$("table[wf_style=rounded]").length)
			WF.container.id = "nothing";
		else
			WF.container.id = "normal";			
		
		
		// Fix the margin with id = nothing
		if (WF.container.id=="nothing") {
			var child = WF.container.firstChild;
			while(child) {
				if (child.nodeType === 1 &&
				    child.id!="header" &&
					child.id!="tab" &&
					child.id!="optionpanel") {
					$(child).addClass("margin");
				}
				child = child.nextSibling;
			}
		}
		
		// Some commands
		if (WF.commands===null) return;
		if (typeof WF.commands["removeTabInfo"]!="undefined") {
			var args = WF.commands["removeTabInfo"];
			var tabIndex = parseInt(args[0]);
			if (WF.Tab.items[tabIndex].infoDiv) {
				$(WF.Tab.items[tabIndex].infoDiv).dispose();
				WF.Tab.items[tabIndex].infoDiv = null;
			}
		}
		else if (typeof WF.commands["updateTabInfo"]!="undefined") {
			var args = WF.commands["removeTabInfo"];
			var tabIndex = parseInt(args[0]);
			var tabitem = WF.Tab.items[tabIndex];
			if (!tabitem.infoDiv) {
				var infoDiv = new Element("div", {"wf_type":"info"});
				infoDiv.injectInside(tabitem.div);
				tabitem.infoDiv = infoDiv;
			}
			tabitem.infoDiv.innerHTML = args[1];
		}
	},
	
	fixIE: function() {
		if (!Browser.Engine.trident) return;
		var els = $$("*[wf_style=align_right]","*[wf_style=rounded]"
		             ,"*[wf_style=icon]","*[wf_style=prompt]"
					 ,"*[wf_style=center]","*[wf_style=alert]"
					 ,"*[wf_style=header]","*[wf_style=fullscreen]");
		for (var i=0; i<els.length; i++) {
			var el = els[i];
			var s = el.getAttribute("wf_style").split(" ");
			for (var j=0; j<s.length; j++) {
				el.addClass("wf_style_"+s[j]);				
			}
		} 
	},
	
	initIPhoneContent:function() {
		WF.buildSearchBar();
		WF.buildArrowLink();
		WF.buildNavLinks();
		WF.buildTable();
		WF.buildForms();
		WF.buildListImage();
		WF.buildMaps();
		WF.buildToolbar();
		
		if (typeof iPhoneInited!="undefined") {
			setTimeout(iPhoneInited, 1500);
		}
	},
	
	clearFloat:function() {
		var floatItems = $$("img[wf_style=icon]", "*[wf_style=prompt]");
		for (var i=0; i<floatItems.length; i++) {
			var floatItem = floatItems[i];
			var next = floatItem.nextSibling;
			while(next && (
			      (next.nodeType!==1) || 
			      (next.nodeType===1&&(next.tagName.toLowerCase()!="div"&&next.tagName.toLowerCase()!="span"))
				 ))
				next = next.nextSibling;
			if (next) {
				next.setAttribute("wf_style", "align_right");
			}
			//floatItems[i].nextSilbing.setAttribute("wf_style","align_right");
			new Element("div", {"styles":{"clear":"both"}}).injectInside(floatItems[i].parentNode);
		}
	},
	
	initBackButton:function(needRefresh) {
		if (WF.views.length) {
			var backButton = new Element("a", {
				id:"backButton",
				"class":"nav",
				"href":"#",
				"events": {
					"click": function(e) {
						new Event(e).stop();
						if (WF.loading) return;
						var level = 1;
						if (WF.commands && typeof WF.commands["back"]!="undefined") {
							level = parseInt(WF.commands["back"]);
							level = level>0?level:1;
						}
						
						var needRefresh = false;
						if (WF.commands && typeof WF.commands["back_refresh"] != "undefined") {
							needRefresh = true;
						}
						
						for (var i=0; i<level; i++) {
							WF.popLastView();	
						}
						
						if (needRefresh) {
							WF.commands["back_refresh"] = [];
							WF.loadLinkContent(WF.activePageLink, false);
						}
					}
				}
			});
			backButton.appendText("Back");
			backButton.injectInside($("header"));
		}
		else {
			var backButton = $$("a[wf_type=back_button]");
			if (backButton.length) {
				backButton = backButton[0];
				backButton.id = "backButton";
				backButton.addClass("nav");
				backButton.injectInside($("header"));
			}
		}
	},
	
	joinURL: function(url) {
		if (url.indexOf("http://")===0) { // Full Path
			return url;
		}
		
		if (url.indexOf("/")===0) { // Absolute Path
			return "http://" + location.host + url;
		}
		
		// Relative path
		return "http://" + location.host + WF.dirName(location.pathname) + url;
	},
	
	dirName: function(pathname) {
		if (pathname.indexOf("/")===pathname.length-1) return pathname;
		var s = pathname.split("/");
		return s.slice(0, s.length-1).join("/") + "/";
	},
	
	strService: function(str) {
		if (str.indexOf("[wf:gps]")>=0&&typeof google.loader.ClientLocation!="undefined") {
			str = str.replace("[wf:gps]", google.loader.ClientLocation.latitude+","+google.loader.ClientLocation.longitude);
		}
		return str;
	},
	
	fixHeaderAndTab: function() {
		if (Browser.Engine.gecko) {
			$("header").setStyle("height","24px");
		}
		
		$("header").addEvent("click", WF.scrollToTop);
		
		if (!Browser.Platform.ipod) {
			var tab = $("tab");
			if (tab) {
				tab.setStyle("width", "320px");	
			}
		}
		
		if ($("tab")&&(!WF.isWebApp)) {
			new Element("div", {"styles":{height:"44px"}}).injectInside(WF.container);
		}
	},
	
	fixScroll:function() {
		var oldPageYOffset = 0;
		var oldOrientation = -1;
		
		setInterval(
			function() {
				var offset = window.pageYOffset;
				if (!Browser.Platform.ipod) {
					offset = WF.container.scrollTop;
				}
				var header = $("header");
				var topbar = $("topbar");
				if (!header) return;

				var orientation = window.orientation;
			
				if (oldPageYOffset==offset&&oldOrientation==orientation) return;
				
				header.setStyle("top", offset + "px");
				if (topbar) topbar.setStyle("top", offset+"px");
				
				var gap = typeof __gap!="undefined"&&__gap;
				var heightOffset = 480-(gap?0:44)-20;
				switch (orientation) {
					
					// If we're horizontal
					case 90:
					case -90:
						heightOffset = 320-(gap?0:32)-20;
					
						// Set orient to landscape
						document.body.setAttribute("orient", "landscape");
						break;	
					
					// If we're vertical
					default:
						// Set orient to portrait
						document.body.setAttribute("orient", "portrait");
						break;
				}

				var tab = $("tab");
				if (tab) {
					tab.setStyle("top", (offset + heightOffset - tab.offsetHeight) + "px");	
				}
				
				/* Button Panel */
				WF.fixOptionPanel();
				
				oldPageYOffset = offset;
				oldOrientation = orientation;
			}, 50
		);		
	},
	
	fixOptionPanel: function() {
		var optionPanel = $("optionpanel");
		if (optionPanel && optionPanel.offsetHeight===0) {
			setTimeout(WF.fixOptionPanel, 50);
			return;
		}
		else if (optionPanel===null) {
			return;
		}

		var offset = window.pageYOffset;
		if (!Browser.Platform.ipod) {
			offset = WF.container.scrollTop;
		}
		var orientation = window.orientation;
		
		var gap = typeof __gap!="undefined"&&__gap;
		var heightOffset = 480-(gap?0:44)-20;
		switch (orientation) {
			
			// If we're horizontal
			case 90:
			case -90:
				heightOffset = 320-(gap?0:32)-20;
			
				// Set orient to landscape
				document.body.setAttribute("orient", "landscape");
				break;	
			
			// If we're vertical
			default:
				// Set orient to portrait
				document.body.setAttribute("orient", "portrait");
				break;
		}
		
		optionPanel.setStyle("top", (offset + heightOffset - optionPanel.offsetHeight) + "px");
	},
	
	buildHeader:function() {
		var header = new Element("div", {id:"header"});
		if (!WF.isWebApp) {
			header.setStyle("position", "relative");
		}
		var h1 = new Element("h1").appendText(document.title).injectInside(header);
		if (header.firstChild) {
			header.injectBefore(WF.container.firstChild, WF.container);			
		}
		else {
			header.injectInside(WF.container);	
		}
		WF.titleTag = h1;
		WF.header = header;
	},
	
	buildListImage:function() {
		var images = $$("img[wf_type=item_img]");
		for (var i=0; i<images.length; i++) {
			var img = images[i];
			img.setStyles({
				"marginLeft":"-90px"	
			});
			$(img.parentNode).setStyle("paddingLeft", "100px")
		}
	},
	
	/* Search Bar */
	buildSearchBar:function() { // run after buildHeader
		var searchForms = $$("form[wf_type=searchbar]");
		
		if (searchForms.length) {
			var topbar = new Element("div", {id:"topbar"});
			
			topbar.inject(WF.header, "after");	

			if (!WF.isWebApp) {
				topbar.setStyle("position", "relative");
			}
			
			for (var i=0; i<searchForms.length; i++) {
				var searchForm = searchForms[i];
				topbar.appendChild(searchForm);
			}
					
			WF.header.setStyle("display", "none");
		}
	},
	
	/* build search form */
	buildForms:function() {
		var forms = $$("form");
		for (var i=0; i<forms.length; i++) {
			var f = forms[i];
			WF.bindForm(f);
			
			if (f.getAttribute("wf_type")=="searchbar") {
				continue;
			}
			
			// beauty the forms
			/*
			var inputs = [];
			for (var j=0; j<f.elements.length; j++) {
				var el = f.elements[j];
				if (((el.tagName.toLowerCase()=="input"&&(el.type=="text"||el.type=="file"||el.type=="password"))||
				    (el.tagName.toLowerCase()=="select"))&&(el.parentNode.tagName.toLowerCase()=="form")) {
					inputs.push(el);
				}
			}
			if (inputs.length) {
				var table = new Element("table").inject(inputs[0], "before");
				var tbody = new Element("tbody").injectInside(table);
				for (var i=0; i<inputs.length; i++) {
					var input = inputs[i];
					var tr = new Element("tr").injectInside(tbody);
					var td = new Element("td").injectInside(tr);
					input.injectInside(td);
					if (input.getAttribute("wf_input_prompt")) {
						var label = new Element("label", {
							"for":input.name,
							"wf_style":"prompt"
						}).appendText(input.getAttribute("wf_input_prompt")+" ").inject(input, "before");
						
						var div = new Element("div", {
							"wf_style":"align_right"
						}).inject(input, "before");
						input.injectInside(div);
						
						new Element("div",{"styles":{"clear":"both"}}).inject(div, "after");						
					}
				}
			}
			*/
		}
		
		// Submit buttons
		var buttons = $$("form input[type=submit]");
		for (var i=0; i<buttons.length; i++) {
			WF.buildSubmitButton(buttons[i]);
		}
	},
	
	buildSubmitButton:function(btn) {
		if (btn.form.parentNode.id!="topbar"&&btn.form.parentNode.getAttribute("wf_type")!="toolbar") {
			btn.setStyle("display", "none");
			var atag = new Element("a", {
				href:"#",
				"class":"button white",
				"events": {
					click: function(e) {
						new Event(e).preventDefault();
						if (document.body.getAttribute("wf_type")=="no_back") {
							btn.form.submit();				
							return;	
						}
						$(btn.form).fireEvent("submit", e);
					}
				}
			}).inject(btn, "after");
			atag.appendText(btn.value);
		}
	},
	
	bindForm:function(f) {
		$(f).addEvent("submit", function(e) {
			new Event(e).preventDefault();
			if (document.body.getAttribute("wf_type")=="no_back") {
				this.submit();				
				return;	
			}
			
			var samelevel = false;
			if (this.getAttribute("wf_type")=="samelevel") {
				samelevel = true;				
			}
			var action = WF.joinURL(this.action);
			new iframe(this, 
				{
					onComplete:function() {
						// this.transport == iframe
						if (action!=WF.activePageLink&&(!samelevel)) {
							if (Browser.Platform.ipod) {
								this.transport.dispose();	
							}
							// Push Current Status
							WF.pushCurrentView();
							if (Browser.Platform.ipod) {
								this.transport.injectInside(document.body);	
							}
						}
						WF.activePageLink = this.transport.contentWindow.location.toString();
						WF.initLinkedPage(this.transport);
						setTimeout(WF.scrollToTop, 500);
					}
				}
			);
		});
	},
	
	/* Table */
	buildTable:function() {
		var tables = $$("table");
		/* all default table is rounded */
		for (var i=0; i<tables.length; i++) {
			if (!tables[i].getAttribute("wf_style")) {
				tables[i].setAttribute("wf_style", "rounded");
			}
		}
		
		/* play with the table to fit content */
		for (var i=0; i<tables.length; i++) {
			WF.fitTableContent(tables[i]);
		}
	},
	
	fitTableContent:function(table) {
		var trs = $(table).getElements("tr");
		if (!trs.length) return;
		
		// get/calculate the fit order
		var noCols = 1;
		for (var i = 0; i < trs.length; i++) {
			if (trs[i].getElements("td").length>noCols) {
				noCols = trs[i].getElements("td").length;
			}
		} // assume no recursive table
		
		if (table.getAttribute("fit_order")) {
			var fit_order = table.getAttribute("fit_order").split(",");
			fit_order.each(parseInt);
		}
		else {
			var fit_order = [];
			for (var i=0; i<noCols; i++) {
				fit_order.push(i);
			}
		}
		
		// fit the content to the column
		// the last column in the order is omitted
		for (var i=0; i<fit_order.length-1; i++) {
			var width = WF.maxWidthCellInCol(trs, fit_order[i]);
			if (width===0) { // haven't rendered anything....
				setTimeout(WF.fitTableContent, 500, table);
				return;
			}
			
			var tds = null;
			for (var j=0; j<trs.length; j++) {
				tds = trs[j].getElements("td");
				if (tds.length===noCols) {
					break;
				}
			}
			if (tds===null) continue;
			console.log(tds.length, noCols, width);
			tds[fit_order[i]].setStyle("width", width+"px");
		}
	},
	
	maxWidthCellInCol:function(trs, col) {
		var maxWidth = 0;
		for (var i=0; i<trs.length; i++) {
			var tds = trs[i].getElements("td");
			if (col>=tds.length) continue;
			if (tds[col].colSpan && parseInt(tds[col].colSpan)>1) continue;
			
			var width = WF.getCellContentWidth(tds[col]);
			if (width>maxWidth) {
				maxWidth = width;
			}
		}
		return maxWidth;
	},
	
	getCellContentWidth:function(cell) {
		// assume each child is fit in one row
		var maxWidth = 0;
		var child = cell.firstChild;
		while(child) {
			if (child.offsetWidth>maxWidth) {
				maxWidth = child.offsetWidth;
			}
			child = child.nextSibling;
		}
		return maxWidth;
	},
	
	/* Navigation Links */
	buildNavLinks:function() {
		if (document.body.getAttribute("wf_type")=="no_back") {
			return;	
		}
		var links = $$("a");
		for (var i=0; i<links.length; i++) {
			if(links[i].id=="backButton") continue;
			WF.bindNavLink(links[i]);
		}
	},
	
	bindNavLink:function(atag) {
		if (document.body.getAttribute("wf_type")=="no_back") {
			return;	
		}
		$(atag).addEvent("click", function(e){
			WF.loadLinkContent(this.href);
			var e = new Event(e);
			e.stop();
		});
	},
	
	loadLinkContent:function(url, needPush) {
		if (WF.loading) return;
		if (!WF.loadingImg) WF.loadingImg = new Element("div", {id:"loading"});
		if (typeof needPush=="undefined") needPush=true;
		
		var myAjax = new Request( {
			url: WF.strService(url),
			async: true,
			method: "get"			
		});
		myAjax.addEvent('onSuccess', WF.loadLinkComplete.bind({
			url: url,
			needPush: needPush
		}));
		myAjax.addEvent('onFailure', WF.loadLinkError);
		 
		WF.loading = true;
		WF.container.appendChild(WF.loadingImg);
		return myAjax.send();
	},
	
	loadLinkComplete:function(text, xml) {
		WF.loadingImg.dispose();
		
		if (this.needPush) {
			// Push Current Status
			WF.pushCurrentView();
		}

		// use iframe
		var iframe = new Element("iframe", {
			"styles": {
				position:"absolute",
				left:"-10000px",
				top:"0px"
			}
		}).injectInside(document.body);

		if (Browser.Engine.webkit) {
			var doc = iframe.contentDocument;
		}
		else {
			var doc = iframe.contentWindow.document;
		}
		doc.open();
		doc.write(text);
		doc.close();
		WF.loading = false;

		WF.activePageLink = WF.joinURL(this.url);
		WF.initLinkedPage(iframe);
		setTimeout(WF.scrollToTop, 500);
	},

	initLinkedPage:function(iframe) {
		var title = iframe.contentWindow.document.title;
		var html = iframe.contentWindow.document.body.innerHTML;
		var wf_commands = {};
		
		// Propagate the back refresh to the prev level
		if (WF.commands && typeof WF.commands["back_refresh"] != "undefined") {
			wf_commands["back_refresh"] = [];
		}
		
		if (iframe.contentWindow.document.body.getAttribute("wf_commands")) {
			// commands are space delimited
			var commands = iframe.contentWindow.document.body.getAttribute("wf_commands").split(" ");
									
			// extract the command and arguments
			for (var i=0; i<commands.length; i++) {
				var command = commands[i];
				var tmp = command.split("(");
				var action = tmp[0];
				if (tmp.length>1) {
					var arguments = tmp[1].split(")")[0].split(",");	
				}
				else {
					var arguments = [];
				}
				wf_commands[action] = arguments;
			}
		}
		WF.commands = wf_commands;
		var isModal = false;
		if (iframe.contentWindow.document.body.getAttribute("wf_type")) {
			isModal = iframe.contentWindow.document.body.getAttribute("wf_type")=="modal";
		}
		$(iframe).dispose();
		// document.body.removeChild(iframe);
		
		var child = WF.container.firstChild;
		while(WF.container.firstChild) {
			WF.container.removeChild(WF.container.firstChild);
		}
		WF.container.innerHTML = html;
		WF.hasTab = WF.Tab && (!isModal);

		WF.initIPhoneView();
		
		WF.titleTag.innerHTML="";
		WF.titleTag.appendText(title);
	},
	
	loadLinkError:function() {
		WF.loadingImg.dispose();
		alert("Error loading");
		WF.loading = false;
	},
	
	pushCurrentView:function() {
		var div = new Element("div");
		if (WF.Tab&&WF.hasTab) {
			WF.Tab.div.dispose();
		}
		
		while(WF.container.firstChild) {
			div.appendChild(WF.container.firstChild);
		}
		
		// Push the states
		WF.views.push(
			{
				div: div,
				hasTab: WF.hasTab,
				titleTag: WF.titleTag,
				header: WF.header,
				map: WF.map,
				activePageLink: WF.activePageLink,
				container_id: WF.container.id,
				commands: WF.commands
			}
		);
		
		WF.titleTag = null;
		WF.header = null;
		WF.map = null;
		WF.commands = null;
	},
	
	popLastView:function() {
		while(WF.container.firstChild) {
			WF.container.removeChild(WF.container.firstChild);
		}
		if (!WF.views.length) return;
		v = WF.views.pop();
		while(v.div.firstChild) {
		   WF.container.appendChild(v.div.firstChild);
		}
		
		// Pop the states
		WF.titleTag = v.titleTag;
		WF.map = v.map;
		WF.hasTab = v.hasTab;
		WF.header = v.header;
		WF.activePageLink = v.activePageLink;
		WF.container.id = v.container_id;
		WF.commands = v.commands;
		
		if (WF.hasTab&&WF.Tab) {
			WF.Tab.div.inject(WF.header, "after");
		}
		
		var height = parseInt($("header").getStyle("top"));
		if (Browser.Platform.ipod) {
			window.scrollTo(0, height);
		}
		else {
			WF.container.scrollTop = height;
		}		
	},
	
	/* ToolBar */
	buildToolbar:function() {
		var toolbarDivs = $$("div[wf_type=toolbar]");
		if (toolbarDivs.length===0) {
			return;
		}
		
		// Only build one toolbar
		var toolbarDiv = toolbarDivs[0];
		for (var i=1; i<toolbarDivs.length; i++) {
			$(toolbarDivs[i]).dispose();
		}
		
		var forms = $$("div[wf_type=toolbar] form");
		// toolbarDiv.id = "toolbar";
		
		// Only build one form first
		if (forms.length==1) {
			var form = forms[0];
			var atag = new Element("a", {
				"class":"nav Action",
				"href":"#"
			}).injectInside($("header"));
			WF.bindToolbarForm(atag, form);
			var child = form.firstChild;
			while(child) {
				if (child.nodeType===1&&child.tagName.toLowerCase()=="input"&&child.type=="submit") {
					$(child).setStyle("display", "none");
					atag.innerHTML=child.value;
					break;
				}
				child = child.nextSibling;
			}
		}
		else if (forms.length>1) { // More button
			var atag = new Element("a", {
				"class":"nav Action",
				"href":"#",
				"events":{
					"click":function(e) {
						new Event(e).preventDefault();
						$("optionpanel").setStyle("display", "");
						WF.fixOptionPanel();
					}
				}
			}).injectInside($("header")).appendText("More");
			
			var optionPanel = new Element("div", {
				id: "optionpanel",
				"styles":{display:"none"}				
			}).injectInside(WF.container);
			var p = new Element("p").injectInside(optionPanel);
			
			for (var i=0; i<forms.length; i++) {
				var form = forms[i];

				var atag = new Element("a", {
					"class":"white button",
					"href":"#"
				}).injectInside(p);
				WF.bindToolbarForm(atag, form);

				var child = form.firstChild;
				while(child) {
					if (child.nodeType===1&&child.tagName.toLowerCase()=="input"&&child.type=="submit") {
						$(child).setStyle("display", "none");
						atag.innerHTML=child.value;
						break;
					}
					child = child.nextSibling;
				}
			}
			
			var atag = new Element("a", {
				"class":"red button",
				"href":"#",
				"events":{
					"click":function(e) {
						new Event(e).preventDefault();
						$("optionpanel").setStyle("display", "none");
					}
				}
			}).injectInside(p).appendText("Hide me");
		}
	},
	
	bindToolbarForm: function(atag, form) {
		atag.addEvent("click", 
			function(e) {
				new Event(e).preventDefault();
				if ($("optionpanel")) {
					$("optionpanel").setStyle("display", "none");
				}
				$(form).fireEvent("submit", e);				
			}
		);
	},
	
	/* Tab */
	buildTab:function() {
		var tabDivs = $$("div[wf_type=tab_bar]");
		if (tabDivs.length&&(!WF.Tab)) {
			// Only build one map
			var tabDiv = tabDivs[0];
			for (var i=1; i<tabDivs.length; i++) {
				$(tabDivs[i]).dispose();
			}
			
			var atabs = tabDiv.getElements("a");
			var tabitems = [];
			for (var i=0; i<atabs.length; i++) {
				var atab = atabs[i];
				var infos = atab.getElements("span[wf_type=info]");
				if (infos.length) {
					for (var j=0; j<infos.length; j++) infos[j].dispose();
				}
				
				var tabitem = {
					img: atab.getAttribute("wf_tab_img")?atab.getAttribute("wf_tab_img"):null,
					img_on: atab.getAttribute("wf_tab_img_active")?atab.getAttribute("wf_tab_img_active"):null,
					url: atab.href,
					title: atab.get('text'),
					info: null,
					infoDiv: null
				};

				if (infos.length) tabitem.info = infos[0].innerHTML;
				tabitems.push(tabitem);
			}
			
			tabDiv.inject(WF.header, "after");
			tabDiv.innerHTML = "";
			tabDiv.id = "tab";
			tabDiv.addClass("tab");
			tabDiv.addClass("tab_"+tabitems.length);
			
			if (!WF.isWebApp) {
				tabDiv.setStyle("position", "absolute");
			}
			
			for (var i=0; i<tabitems.length&&i<5; i++) {
				var tabitem = tabitems[i];
				var div = new Element("div", {
					"class": "tabitem",
					title: tabitem.title
				}).injectInside(tabDiv);
				
				var img = new Element("img", {
					src: tabitem.img,
					title: tabitem.title
				}).injectInside(div);
				
				var textDiv = new Element("div", {
					"class":"title"
				}).appendText(tabitem.title).injectInside(div);
				
				if (tabitem.info!==null) {
					var infoDiv = new Element("div", {"wf_type":"info"});
					infoDiv.appendText(tabitem.info);
					infoDiv.injectInside(div);
					tabitem.infoDiv = infoDiv;
				}
				
				WF.bindTabItem(div, tabitem);
				tabitem.imgtag = img;
				tabitem.div = div;
			}
			
			new Element("div", {
				"styles":{"clear":"both"}
			}).injectInside(tabDiv);
			
			new Element("div", {
				id: "content",
				"styles": {
					"marginBottom":"44px"
				}
			}).injectInside(WF.container);
						
			WF.Tab = {
				div: tabDiv,
				items: tabitems,
				active: null
			};
			
			WF.hasTab = true;
			
			if (tabitems.length>5) {
				alert("Some tabs are ignored.");
			}
			
		}
		else if (WF.Tab&&WF.hasTab) {
			WF.Tab.div.inject(WF.header, "after");
		}
	},
	
	bindTabItem:function(img, tabitem) {
		img.addEvent("click", function() {
			while(WF.views.length) { // Pop to the top 
				WF.popLastView();
			}
			WF.loadTabContent(tabitem);
		});
	},
	
	loadTabContent:function(tabitem) {
		if (WF.loading) return;
		if (WF.Tab.active===tabitem) return;
		if (!WF.loadingImg) WF.loadingImg = new Element("div", {id:"loading"});
				
		var myAjax = new Request( {
			url: WF.strService(tabitem.url),
			async: true,
			method: "get"			
		});
		myAjax.addEvent('onSuccess', WF.loadTabComplete.bind(tabitem));
		myAjax.addEvent('onFailure', WF.loadTabError);
		 
		WF.loading = true;
		return myAjax.send();
	},
	
	loadTabComplete:function(text, xml) {
		// use iframe
		var iframe = new Element("iframe", {
			"styles": {
				position:"absolute",
				left:"-10000px",
				top:"0px"
			}
		}).injectInside(document.body);
		if (Browser.Engine.webkit) {
			var doc = iframe.contentDocument;
		}
		else {
			var doc = iframe.contentWindow.document;
		}
		doc.open();
		doc.write(text);
		doc.close();
		WF.loadingImg.dispose();
		WF.loading = false;
		
		WF.activePageLink = WF.joinURL(this.url); 
		WF.initLinkedPage(iframe);
		
		// highlight tab image
		var tabitem = this;
		tabitem.imgtag.src = tabitem.img_on;
		$(tabitem.imgtag.parentNode).addClass("on");
		if (WF.Tab.active&&WF.Tab.active!==tabitem) {
			WF.Tab.active.imgtag.src = WF.Tab.active.img;
			$(WF.Tab.active.imgtag.parentNode).removeClass("on");
		}
		WF.Tab.active = tabitem;

		setTimeout(WF.scrollToTop, 500);
	},
	/*
	initTabPage:function(iframe) {
		if ($("topbar")) {
			$("topbar").dispose();
			WF.header.setStyle("display","");
		}
		var actions = $$("div#header a.Action");
		for (var i=0; i<actions.length; i++) {
			actions[i].dispose();
		}
		var c = $("content");
		WF.titleTag.innerHTML="";
		WF.titleTag.appendText(iframe.contentWindow.document.title);
		c.innerHTML = iframe.contentWindow.document.body.innerHTML;
		WF.initIPhoneContent();
		document.body.removeChild(iframe);
	},*/
	
	loadTabError:function() {
		WF.loadingImg.dispose();
		alert("Error!");
		WF.loading = false;
	},
	
	/* Link in Item */
	buildArrowLink:function() {
		var els = $$("td");
		for (var i=0; i<els.length; i++) {
			var el = els[i];
			var child = el.firstChild;
			while(child&&child.nodeType!==1) {
				child = child.nextSibling;
			}
			
			if (child&&child.tagName.toLowerCase()=="a") {
				$(child).addClass("arrow");
				$(el.parentNode).addClass("arrow");
				WF.bindRowLink($(el.parentNode), child.href);
			}
		}
	},
	
	bindRowLink:function(tr, url) {
		if (document.body.getAttribute("wf_type")=="no_back") {
			return;	
		}
		$(tr).addEvent("click", function(e){
			WF.loadLinkContent(url);
			var e = new Event(e);
			e.stop();
		});
	},
	
	/* Map */
	buildMaps:function() {
		var mapDivs = $$("div[wf_type=map]");
		
		if (mapDivs.length) {
			GMap2 = google.maps.Map2;
			if (typeof GMap2 == "undefined" || typeof LabeledMarker == "undefined") {
				alert("Please import map javascript");
				return;
			}

			// Only build one map
			setTimeout(function() {
				WF.buildMap(mapDivs[0]);
				for (var i=1; i<mapDivs.length; i++) {
					$(mapDivs[i]).dispose();
				}
			},500);
			
			WF.header.setStyle("position", "relative");
			if (WF.Tab&&WF.Tab.div) {
				if (WF.isWebApp) {
					WF.Tab.div.setStyle("position", "relative");	
				}
				else {
					WF.Tab.div.setStyle("position", "absolute");	
				}				
			}
		}
	},
	
	buildMap:function(mapNode) {
		mapNode = $(mapNode);
		
		/* Parse map information */
		var center = mapNode.getAttribute("wf_map_center").split(",");
		center[0] = parseFloat(center[0]);
		center[1] = parseFloat(center[1]);
		
		var amaps = mapNode.getElements("a");
		var flags = [];
		for (var i=0; i<amaps.length; i++) {
			var amap = amaps[i];
			var flag = {
				location: amap.getAttribute("wf_geo_location").split(","),
				description: "",
				title: amap.get("text"),
				url: amap.href
			};
			flags.push(flag);
		}
		/*
		while (child) {
			if (child.nodeType===1&&child.getAttribute("wf_type")=="map_flag") {
				var flag = {
					location: child.getAttribute("wf_map_flag_location").split(","),
					description: child.getAttribute("wf_map_flag_description"),
					title: child.getAttribute("wf_map_flag_title"),
					url: child.getAttribute("wf_map_flag_target_url")
				};
				$(child).appendText(flag.title);
				flags.push(flag);
			}
			child = child.nextSibling;
		}
		*/
		mapNode.innerHTML="";
		mapDiv = new Element("div").injectInside(mapNode.parentNode);
		mapNode.dispose();
		mapDiv.addClass("wf_map");
		
		if (GBrowserIsCompatible()){
			map = new GMap2(mapDiv);
			/*yslider = new YSliderControl();
	    		yslider.initialize(map);
	    		var ttop= Math.round((YSLIDERLENGTH/MAXZOOM*12));
	    		yslider.slide.top =  ttop;
	    		yslider.knob.style.top = ttop+"px";*/
			map.addMapType(G_NORMAL_MAP);
			map.setCenter(new GLatLng(center[0], center[1]), 17, G_NORMAL_MAP);
			if (!Browser.Platform.ipod) {
				map.enableScrollWheelZoom()
			}
			var imap = new WF.iPhoneGMap(map);
			
			for (var i=0; i<flags.length; i++) {
				var flag = flags[i];
		        var marker = new LabeledMarker(new GLatLng(parseFloat(flag.location[0]), parseFloat(flag.location[1])), 
					{
						"clickable": true,
						"title": flag.title,
						"labelText": flag.url?'<a href="' + flag.url + '">' +
										flag.title + '</a>':flag.title,
						"labelOffset": new GSize(-50, 0),
						"labelClass": "wf_map_flag_label"
					});
				map.addOverlay(marker);
				WF.bindMarker(marker, flag);
			}
			
			var atags = mapDiv.getElements("a");
			for (var i=0; i<atags.length; i++) {
				if (atags[i].id=="backButton") continue;
				WF.bindNavLink(atags[i]);
			}
			
			WF.map = map;
		}		
	},
	
	bindMarker: function(marker, flag) {
		if (!flag.url) return;
		GEvent.addListener(marker, "click", function() {
			WF.loadLinkContent(flag.url);
		});
	},
	
	/* from dyasdesigns */
	iPhoneGMap:function(mapvar, mapdiv) {
		this.map = mapvar;
		if(typeof mapdiv == "undefined"){
			this.mapDiv = this.map.getContainer();
		}
		else this.mapDiv = mapdiv;
		
		this.touchPositionX = 0;
		this.touchPositionY = 0;
		this.isZooming = false;
		this.webkitTranslateX = 0;
		this.webkitTranslateY = 0;
		var centerPoint = this.map.fromLatLngToDivPixel(this.map.getCenter());
		this.mapCenterX = centerPoint.x;
		this.mapCenterY = centerPoint.y;
		var that = this;
		
		this.mapDiv.ongestureend = function(e) {
			that.isZooming = false;
			that.webkitTranslateX = 0;
			that.webkitTranslateY = 0;
		};
		
		this.mapDiv.ongesturechange = function(e) {
			e.preventDefault();
			if(!that.isZooming){
				var z = Math.log(e.scale)/Math.log(2)*2.0;
				var oldZoom = that.map.getZoom();
				var zoom = parseInt(that.map.getZoom() + z);
				if (oldZoom!=zoom) {
					that.map.setZoom(zoom);
					that.isZooming = true;
				}
			}
		};
	}
};


/*
based on prototype's && moo.fx's ajax class
to be used with prototype.lite, in conjunction with moo.AJAX
this submits an iframe invisibly to the server, and expects a JSON object in return
handy, so that you do not have to care about posting forms, urlencoding, file uploads etc.
usage: <form method='post' onsubmit='new iframe(this); return false;'>

changelog:
17-01-06: initial release
18-01-06: added options initiator
          added IE5 support
		  added Opera support
01-03-06: added WORKING safari support! Major thanks to Charles Hinshaw and Phil Barrett!

*/
document.iframeLoaders = {};

iframe = new Class({
	initialize: function(form, options){
		if (!options) options = {};
		this.form = form;
		this.uniqueId = new Date().getTime();
		document.iframeLoaders[this.uniqueId] = this;
		this.transport = this.getTransport();
		this.onComplete = options.onComplete || null;
		this.update = $(options.update) || null;
		this.updateMultiple = options.multiple || false;
		form.target= 'frame_'+this.uniqueId;
		form.setAttribute("target", 'frame_'+this.uniqueId); // in case the other one fails.
		form.submit();
	},

	onStateChange: function(){
		this.transport = $('frame_'+this.uniqueId);
		try {   var doc = this.transport.contentDocument.document.body.innerHTML; this.transport.contentDocument.document.close(); }	// For NS6
		catch (e){ 
			try{ var doc = this.transport.contentWindow.document.body.innerHTML; this.transport.contentWindow.document.close(); } // For IE5.5 and IE6
			 catch (e){
				 try { var doc = this.transport.document.body.innerHTML; this.transport.document.body.close(); } // for IE5
					catch (e) {
						try	{ var doc = window.frames['frame_'+this.uniqueId].document.body.innerText; } // for really nasty browsers
						catch (e) { } // forget it.
				 }
			}
		}
		this.transport.responseText = doc;
		if (this.onComplete) setTimeout(function(){this.onComplete(this.transport);}.bind(this), 10);
		if (this.update) setTimeout(function(){this.update.innerHTML = this.transport.responseText;}.bind(this), 10);
		if (this.updateMultiple){ setTimeout(function(){ // JSON support!
				try	{ var hasscript = false; eval("var inputObject = "+this.transport.responseText);	// we're expecting a JSON object, eval it to inputObject
					for (var i in inputObject) { if (i == 'script') { hasscript = true; } // check if we passed some javascript along too
						else {if ( elm = $(i)) { elm.innerHTML = inputObject[i]; } else { alert("element "+i+" not found!"); } } // if it's not script, update the corresponding div
					} if (hasscript) eval(inputObject['script']); // some on-the-fly-javascript exchanging support too
				} catch (e) { alert('There was an error processing: '+this.transport.responseText); } // in case of an error					
			}.bind(this), 10);
		}	
	},

	getTransport: function() 
	{
		var divElm = document.createElement('DIV');
	    divElm.style.position = "absolute";
        divElm.style.top = "0";
        divElm.style.marginLeft = "-10000px";
		if (navigator.userAgent.indexOf('MSIE') > 0 && navigator.userAgent.indexOf('Opera') == -1) {// switch to the crappy solution for IE
		 divElm.innerHTML = '<iframe name=\"frame_'+this.uniqueId+'\" id=\"frame_'+this.uniqueId+'\" src=\"about:blank\" onload=\"setTimeout(function(){document.iframeLoaders['+this.uniqueId+'].onStateChange()},20);"></iframe>';
		} else {
			var frame = document.createElement("iframe");
			frame.setAttribute("name", "frame_"+this.uniqueId);
			frame.setAttribute("id", "frame_"+this.uniqueId);
			frame.addEventListener("load", 	function(){	this.onStateChange(); }.bind(this), false);
			divElm.appendChild(frame);
		}
		document.getElementsByTagName("body").item(0).appendChild(divElm);
	}
});
